<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <script src="jquery.min.js"></script>
    <title>小豌豆</title>
    <style>
        html,
        body {
          height: 100%;
        }

        body {
          display: flex;
          align-items: center;
          justify-content: center;
          background: #1e2779;
          margin: 0;
        }

        .peas {
          width: 200px;
        }

        .pea-1 .body,
        .pea-1 .cheek {
          fill:#6BC566;
        }

        .pea-2 .body,
        .pea-2 .cheek {
          fill:#B9EA77;
        }

        .pea-3 .body,
        .pea-3 .cheek {
          fill:#89D770;
        }

        .cheek {
          transition: transform 0.3s;
        }

        .pea:hover .cheek {
          transform: translateY(-1.5px);
        }

        .mouth, .pupil {fill:#002B3E;}
        .tongue {fill:#CE4C59;}
        .eye {fill:#FFFFFF;}
        .base-bottom{fill:#007E61;}
        .base-top{fill:#00905F;}

        .pea-1 .pupil {transition: transform 0.4s linear;}
        .pea-2 .pupil {transition: transform 0.15s linear;}
        .pea-3 .pupil {transition: transform 0.7s linear;}

        .test {
          width: 4px;
          height: 4px;
          background:red;
          border-radius: 100%;
          position: absolute;
          top: 0;
          left: 0;
          transform: translate(-50%, -50%);
        }
    </style>
</head>
<body>
        <svg version="1.1" class="peas" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 100 50" style="enable-background:new 0 0 100 50;" xml:space="preserve">
            <g class="pea pea-3">
              <ellipse class="body" cx="80.5" cy="20" rx="19.5" ry="20"/>
              <path class="mouth" d="M77.9,19.5c-0.2,0-0.4,0-0.5,0.1c-0.7,0.3-0.9,1.1-0.7,1.8c0.7,2,2.6,3.5,4.9,3.5 c2.3,0,4.3-1.6,5-3.8c0.1-0.3,0.1-0.6-0.1-0.8c-0.2-0.5-0.7-0.8-1.3-0.8H77.9z"/>
              <path class="tongue" d="M85.2,23.3c-1-1.1-2.4-1.8-4-1.8c-1.4,0-2.7,0.6-3.7,1.5c1,1.2,2.4,1.9,4,1.9 C83,24.9,84.3,24.3,85.2,23.3z"/>
              <ellipse class="eye eye-right" cx="88.5" cy="12" rx="5" ry="5"/>
              <ellipse class="pupil pupil-right" cx="86.6" cy="12.8" rx="1.8" ry="1.8"/>
              <ellipse class="eye eye-left" cx="74.6" cy="12" rx="5" ry="5"/>
              <ellipse class="pupil pupil-left" cx="76.5" cy="12.8" rx="1.8" ry="1.8"/>
              <path class="cheek cheek-left" d="M79.1,19c-0.9-1.2-2.3-1.9-3.9-1.9s-3,0.8-3.9,1.9"/>
                <path class="cheek cheek-right" d="M92.9,19C92,17.8,90.6,17,89.1,17s-3,0.8-3.9,1.9"/>
            </g>
            <g class="pea pea-1">
              <ellipse class="body" cx="19.5" cy="20" rx="19.5" ry="20"/>
              <path class="mouth" d="M14.6,19.5c-0.2,0-0.4,0-0.5,0.1c-0.7,0.3-0.9,1.1-0.7,1.8c0.7,2,2.6,3.5,4.9,3.5 c2.3,0,4.3-1.6,5-3.8c0.1-0.3,0.1-0.6-0.1-0.8c-0.2-0.5-0.7-0.8-1.3-0.8H14.6z"/>
              <path class="tongue" d="M21.9,23.3c-1-1.1-2.4-1.8-4-1.8c-1.4,0-2.7,0.6-3.7,1.5c1,1.2,2.4,1.9,4,1.9 C19.7,24.9,21,24.3,21.9,23.3z"/>
              <ellipse class="eye eye-right" cx="25.3" cy="12" rx="5" ry="5"/>
              <ellipse class="pupil pupil-right" cx="23.4" cy="12.8" rx="1.8" ry="1.8"/>
              <ellipse class="eye eye-left" cx="11.4" cy="12" rx="5" ry="5"/>
              <ellipse class="pupil pupil-left" cx="13.2" cy="12.8" rx="1.8" ry="1.8"/>      
              <path class="cheek cheek-left" d="M11.4,17c-1.6,0-3,0.8-3.9,1.9h7.8C14.3,17.8,12.9,17,11.4,17z"/>
                <path class="cheek cheek-right" d="M25.2,17c-1.6,0-3,0.8-3.9,1.9H29C28.1,17.8,26.7,17,25.2,17z"/>
            </g>
            <g class="pea pea-2">
              <ellipse class="body" cx="50" cy="20" rx="19.5" ry="20"/>
              <path class="mouth" d="M47.1,19.5c-0.2,0-0.4,0-0.5,0.1c-0.7,0.3-0.9,1.1-0.7,1.8c0.7,2,2.6,3.5,4.9,3.5 c2.3,0,4.3-1.6,5-3.8c0.1-0.3,0.1-0.6-0.1-0.8c-0.2-0.5-0.7-0.8-1.3-0.8H47.1z"/>
              <path class="tongue" d="M54.5,23.3c-1-1.1-2.4-1.8-4-1.8c-1.4,0-2.7,0.6-3.7,1.5c1,1.2,2.4,1.9,4,1.9 C52.2,24.9,53.5,24.3,54.5,23.3z"/>
              <ellipse class="eye eye-right" cx="57.8" cy="12" rx="5" ry="5"/>
              <ellipse class="pupil pupil-right" cx="55.9" cy="12.8" rx="1.8" ry="1.8"/>
              <ellipse class="eye eye-left" cx="43.9" cy="12" rx="5" ry="5"/>
              <ellipse class="pupil pupil-left" cx="45.8" cy="12.8" rx="1.8" ry="1.8"/>
              <path class="cheek cheek-left" d="M47.8,19c-0.9-1.2-2.3-1.9-3.9-1.9s-3,0.8-3.9,1.9"/>
                <path class="cheek cheek-right" d="M61.6,19c-0.9-1.2-2.3-1.9-3.9-1.9s-3,0.8-3.9,1.9"/>
            </g>
            <path class="base-bottom" d="M50,29.8c-19.9,0-37.7-3.8-49.9-9.7c0,0.3,0,0.7,0,1C0,37.1,22.4,50,50,50s50-12.9,50-28.9 c0-0.3,0-0.7,0-1C87.7,26.1,69.9,29.8,50,29.8z"/>
            <path class="base-top" d="M49.5,29.8C30.1,29.8,12.9,26.6,0,20c10.8,13.5,29.2,22.4,50,22.4c20.8,0,39.2-8.8,50-22.4 C86.9,26.9,69.1,29.8,49.5,29.8z"/>
          </svg>

          
          <script>
              'use strict';

                const svg = document.querySelector('.peas');
                let mouseX = 0;
                let mouseY = 0;
                let pupilPadding = 1.5;

                window.addEventListener('mousemove', mouseMove);

                function mouseMove(e) {
                  mouseX = e.clientX;
                  mouseY = e.clientY;
                }

                class Pea {
                  constructor(className) {
                    this.pea = svg.querySelector(className);
                    this.eyeLeft = {
                      element: this.pea.querySelector('.eye-left'),
                      get radius() { return parseInt(this.element.getAttribute('rx')) },
                      get xMin() { return parseInt(this.element.getAttribute('cx')) - this.radius + pupilPadding },
                      get xMax() { return parseInt(this.element.getAttribute('cx')) + this.radius - pupilPadding },
                      get yMin() { return parseInt(this.element.getAttribute('cy')) - this.radius + pupilPadding },
                      get yMax() { return parseInt(this.element.getAttribute('cy')) + this.radius - pupilPadding },
                      get center() { return getItemCenter(this.element.getAttribute('cx'), this.element.getAttribute('cy')) }
                    };
                    this.eyeRight = {
                      element: this.pea.querySelector('.eye-right'),
                      get radius() { return parseInt(this.element.getAttribute('rx')) },
                      get xMin() { return parseInt(this.element.getAttribute('cx')) - this.radius + pupilPadding },
                      get xMax() { return parseInt(this.element.getAttribute('cx')) + this.radius - pupilPadding },
                      get yMin() { return parseInt(this.element.getAttribute('cy')) - this.radius + pupilPadding },
                      get yMax() { return parseInt(this.element.getAttribute('cy')) + this.radius - pupilPadding },
                      get center() { return getItemCenter(this.element.getAttribute('cx'), this.element.getAttribute('cy')) }
                    };
                    this.pupilLeft = {
                      element: this.pea.querySelector('.pupil-left'),
                      get radius() { return parseInt(this.element.getAttribute('rx')) },
                      get center() { return getItemCenter(this.element.getAttribute('cx'), this.element.getAttribute('cy')) }
                    }
                    this.pupilRight = {
                      element: this.pea.querySelector('.pupil-right'),
                      get radius() { return parseInt(this.element.getAttribute('rx')) },
                      get center() { return getItemCenter(this.element.getAttribute('cx'), this.element.getAttribute('cy')) }
                    }
                
                    this.pupilLeft.element.setAttribute('cx', this.eyeLeft.xMin + (this.pupilLeft.radius * 2));
                    this.pupilLeft.element.setAttribute('cy', this.eyeLeft.yMin + (this.pupilLeft.radius * 2));
                
                    this.pupilRight.element.setAttribute('cx', this.eyeRight.xMin + (this.pupilRight.radius * 2));
                    this.pupilRight.element.setAttribute('cy', this.eyeRight.yMin + (this.pupilRight.radius * 2));
                
                    this.pea.addEventListener('mouseenter', function() {
                      this.classList.add('pea-hovered');
                    });

                    this.pea.addEventListener('mouseleave', function() {
                      this.classList.remove('pea-hovered');
                    });
                  }
              
                  update() {
                    let amountY = (this.eyeLeft.yMax - this.eyeLeft.yMin - (this.pupilLeft.radius * 3)) * (mouseY/document.body.clientHeight);
                    let amountX = (this.eyeLeft.xMax - this.eyeLeft.xMin - (this.pupilLeft.radius * 3)) * (mouseX/document.body.clientWidth);
                    this.pupilLeft.element.style.transform = `translate(${amountX}px, ${amountY}px)`;
                    this.pupilRight.element.style.transform = `translate(${amountX}px, ${amountY}px)`;
                  }
                }

                const peas = [
                  new Pea('.pea-1'),
                  new Pea('.pea-2'),
                  new Pea('.pea-3')
                ];

                function loop() {
                  for (let pea of peas) {
                    pea.update();
                  }
              
                  requestAnimationFrame(loop);
                }

                loop();

                function getItemCenter(x, y) {
                  return {
                    x: document.body.clientWidth/2 - svg.clientWidth/2 + (x * window.devicePixelRatio),
                    y: document.body.clientHeight/2 - svg.clientHeight/2 + (y * window.devicePixelRatio)
                  };
                }
          </script>
</body>
</html>